package demo.utils;

import demo.model.RedisProfiling;
import org.aspectj.lang.JoinPoint;
import redis.clients.jedis.Connection;
import redis.clients.jedis.Protocol.Command;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class JedisProfilingUtil {

    private static final ThreadLocal<RedisProfiling> JedisThreadLocal = new ThreadLocal<>();

    public static void beforeSendCmd(JoinPoint joinPoint) {

        Object[] args = joinPoint.getArgs();
        Command cmd = (Command) args[0];
        byte[][] arg = (byte[][]) args[1];
        int argSize = 0;
        String key = "";
        if (arg != null && arg.length > 0) {
            for (byte[] bytes : arg) {
                argSize += bytes.length;
            }
            key = new String(arg[0]);
        }

        System.out.println(Arrays.toString(args));
        Connection target = (Connection) joinPoint.getTarget();
        String host = target.getHost();
        int port = target.getPort();
        String redisInstance = String.format("%s:%s", host, port);
        RedisProfiling vo = new RedisProfiling();
        vo.setApp_name("");
        vo.setApp_host("");
        vo.setApp_ip("");
        vo.setR_instance(redisInstance);
        vo.setR_start(System.currentTimeMillis());
        vo.setR_cmd(cmd.name().toLowerCase());
        vo.setR_key(key);
        //////
//        vo.setR_end(System.currentTimeMillis());
        vo.setR_arg_size(argSize);
//        vo.setR_value_size();
        System.out.println(vo);
        JedisThreadLocal.set(vo);
    }

    public static void afterReturn(Object object) {
        RedisProfiling vo = JedisThreadLocal.get();
        if (vo == null) {
            return;
        }
        vo.setR_end(System.currentTimeMillis());
        int size = objSize(object);
        vo.setR_value_size(size);
        System.out.println(vo);
        JedisThreadLocal.remove();
    }

    /**
     * 求传输对象大小
     *
     * @param object
     * @return
     */
    public static int objSize(Object object) {
        if (object == null) {
            return 0;
        }
        try {
            int size = 0;
            if (object instanceof Collection) {
                for (Object o : ((Collection) object)) {
                    size += _objSize(o);
                }
            } else {
                size = _objSize(object);
            }
            return size;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 求传输对象大小
     *
     * @param object
     * @return
     */
    private static int _objSize(Object object) {
        if (object == null) {
            return 0;
        }
        if (object instanceof byte[]) {
            return ((byte[]) object).length;
        } else if (object instanceof Number) {
            return 8;
        } else if (object instanceof String) {
            return ((String) object).getBytes().length;
        } else {
            return SerializeUtil.objectSize(object);
        }
    }
}
